package com.galaxy.coupon.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.galaxy.common.core.domain.R;
import com.galaxy.coupon.domain.CouponTemplate;
import com.galaxy.coupon.domain.UserCoupon;
import com.galaxy.coupon.domain.bo.UserCouponBo;
import com.galaxy.coupon.domain.convert.UserCouponConvert;
import com.galaxy.coupon.domain.vo.UserCouponVo;
import com.galaxy.coupon.feign.RemoteUserService;
import com.galaxy.coupon.mapper.CouponTemplateMapper;
import com.galaxy.coupon.mapper.UserCouponMapper;
import com.galaxy.coupon.service.IUserCouponService;
import com.galaxy.common.mybatis.core.page.PageQuery;
import com.galaxy.common.mybatis.core.page.TableDataInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * 用户优惠券Service业务层处理
 */
@RequiredArgsConstructor
@Service
public class UserCouponServiceImpl implements IUserCouponService {

    private final UserCouponMapper baseMapper;

    private final RemoteUserService remoteUserService;

    private final CouponTemplateMapper couponTemplateMapper;



    @DS("slave")
    @Override
    public TableDataInfo<UserCouponVo> queryPage(UserCouponBo bo, PageQuery pageQuery) {
        List<UserCouponVo> page = baseMapper.selectAllUserCouponWithCoupons(bo);
        return TableDataInfo.build(page);
    }

    @DS("slave")
    @Override
    public UserCouponVo getInfo(Long id) {
        return baseMapper.selectUserCouponWithCouponById(id);
    }

    @Override
    public Boolean insertByBo(UserCouponBo bo) {
        UserCoupon add = UserCouponConvert.INSTANCE.convert(bo);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean addUserCoupon(UserCouponBo bo) {
//        Long l = baseMapper.selectCount(new LambdaQueryWrapper<UserCoupon>().eq(UserCoupon::getCouponId, bo.getCouponId()));
        CouponTemplate couponTemplate = couponTemplateMapper.selectById(bo.getCouponId());
        if(couponTemplate.getTotalCount()!= -1 && couponTemplate.getTotalCount() < couponTemplate.getReceiveCount()+1){
            throw new RuntimeException("优惠券已领取完毕");
        }

        UserCoupon add = UserCouponConvert.INSTANCE.convert(bo);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        UpdateWrapper<CouponTemplate> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("receive_count", couponTemplate.getReceiveCount()+1) // 将 receiveCount 字段加 1
            .eq("id", bo.getCouponId()); // 条件：id = bo.getCouponId()

// 执行更新
        couponTemplateMapper.update(null, updateWrapper);
        if (flag) {
            bo.setId(add.getId());
            R<Boolean> booleanR = remoteUserService.updateAvatar(bo.getUserId(), bo.getPoints());
            if (booleanR.getData()== null || !booleanR.getData()) {
                throw new RuntimeException("更新用户积分失败");
            }
        }
        return flag;
    }

    @Override
    public Boolean updateByBo(UserCouponBo bo) {
        UserCoupon update = UserCouponConvert.INSTANCE.convert(bo);
        validEntityBeforeSave(update);
        if(bo.getStatus() == 1 && bo.getOrderNo() != null && bo.getUseTime() != null){
            CouponTemplate couponTemplate = couponTemplateMapper.selectById(bo.getCouponId());
            couponTemplateMapper.update(
                null,
                new LambdaUpdateWrapper<CouponTemplate>()
                    .set(CouponTemplate::getUsedCount, couponTemplate.getUsedCount()+1) // 将 usedCount 字段加 1
                    .eq(CouponTemplate::getId, bo.getCouponId()) // 条件：id = bo.getCouponId()
            );
        }
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Boolean deleteById(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public Boolean updateUserCoupon(String orderNo) {
        if(orderNo != null){
            UserCouponVo userCouponVo = baseMapper.selectVoOne(new LambdaQueryWrapper<UserCoupon>().eq(UserCoupon::getOrderNo, orderNo));
            if(userCouponVo != null){
                int update = baseMapper.update(
                    null,
                    new LambdaUpdateWrapper<UserCoupon>()
                        .set(UserCoupon::getStatus, 0)
                        .set(UserCoupon::getOrderNo, null)
                        .set(UserCoupon::getUseTime, null)
                        .eq(UserCoupon::getOrderNo, orderNo)
                );
                CouponTemplate couponTemplate = couponTemplateMapper.selectById(userCouponVo.getCouponId());
                couponTemplateMapper.update(
                    null,
                    new LambdaUpdateWrapper<CouponTemplate>()
                        .set(CouponTemplate::getUsedCount, couponTemplate.getUsedCount()-1) // 将 usedCount 字段减 1
                        .eq(CouponTemplate::getId, userCouponVo.getCouponId()) // 条件：id = userCouponVo.getCouponId()
                );
                return update > 0;
            }else{
                return true;
            }
        }else{
            return false;
        }

    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(UserCoupon entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<UserCoupon> buildQueryWrapper(UserCouponBo bo) {
        LambdaQueryWrapper<UserCoupon> lqw = new LambdaQueryWrapper<>();
        lqw.eq(bo.getId() != null, UserCoupon::getId, bo.getId());
        lqw.eq(bo.getUserId() != null, UserCoupon::getUserId, bo.getUserId());
        lqw.eq(bo.getCouponId() != null, UserCoupon::getCouponId, bo.getCouponId());
        lqw.eq(bo.getStatus() != null, UserCoupon::getStatus, bo.getStatus());
        lqw.eq(bo.getGetType() != null, UserCoupon::getGetType, bo.getGetType());
        return lqw;
    }
}
